package com.wang.tool.monitor.aop;

import com.wang.tool.util.SimpleLogUtil;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.aop.Advisor;
import org.springframework.aop.ProxyMethodInvocation;
import org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor;
import org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;

/**
 * @Author wangshaopeng
 * @Date 2022/5/10
 */
public class MonitorConfiguration {

    @Bean("monitorAdvisor1")
    @ConditionalOnMissingBean(name = "monitorAdvisor1")
    public Advisor monitorAdvisor1(@Autowired MonitorAdvisorOrder order) {
        MonitorAdvice monitorAdvice = new MonitorAdvice();
        Advice advice = (MethodInterceptor) invocation -> monitorAdvice.monitorAround(new MethodInvocationProceedingJoinPoint((ProxyMethodInvocation) invocation));
        AspectJExpressionPointcutAdvisor advisor = new AspectJExpressionPointcutAdvisor();
        String expression =
                //方法/类注解
                "@annotation(" + Monitor.class.getName() + ")"
                        //public
                        + " && execution(public * *(..))"
                        //非Object自带函数
                        + " && !execution(public java.lang.String toString())"
                        + " && !execution(public int hashCode())"
                        + " && !execution(public boolean equals(java.lang.Object))";
        advisor.setExpression(expression);
        advisor.setOrder(order.getOrder());
        advisor.setAdvice(advice);
        SimpleLogUtil.info("[{0}IsAvailable] order:{1}, expression:{2}", Monitor.class.getName(), order.getOrder(), expression);
        return advisor;
    }

}
